﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Xml.Linq;
using System.Web.Routing;
using Microsoft.Practices.Unity;
using Vit.Common;
using Vit.Common.Providers;
using Vit.Common.Extensions;
using Vit.Web;
using Vit.Web.Models;
using Vit.Web.Providers;
using Vit.Web.Helpers;

namespace Vit.Web.Models
{
    public class PageWidget
    {
        [Key]
        [StringLength(50)]
        [Column(Order = 1)]
        [Required]
        public string WebPageName { get; set; }
        [Key]
        [StringLength(50)]
        [Column(Order = 2)]
        [Required]
        public string SectionName { get; set; }
        [Key]
        [Column(Order = 3)]
        [Required]
        public int Order { get; set; }

        [Required]
        [StringLength(50)]
        public string WidgetName { get; set; }

        public int? CacheSeconds { get; set; }

        [StringLength(50)]
        public string Container { get; set; }

        [StringLength(2000)]
        [DataType(DataType.MultilineText)]
        [AllowHtml]
        public string Parameters { get; set; }

        public virtual WebPage Page { get; set; }

        public IHtmlString RenderContents(WebViewPage view, PageMode pageMode)
        {
            if (CacheSeconds.HasValue && CacheSeconds.Value > 0 && Cache != null)
            {
                string key = BuildCacheKey(view, pageMode, "Contents");
                if (Cache.Contains(key))
                    return Cache.GetData(key) as IHtmlString;

                IHtmlString html = RenderContentsInternal(view, pageMode);
                Cache.Add(key, html, PortalHelper.CacheDependency, new TimeSpan(0, 0, CacheSeconds.Value), DateTime.MaxValue);
                return html;
            }
            return RenderContentsInternal(view, pageMode);
        }

        //private IHtmlString RenderContentsWithPageMode(WebViewPage view, string sectionName, PageMode pageMode)
        //{
        //    if ((pageMode & PageMode.Design) == PageMode.Design)
        //    {
        //        ViewDataDictionary viewData = new ViewDataDictionary();
        //        viewData.Add("PageWidget", this);
        //        viewData.Add("Section", sectionName);
        //        return view.Html.Partial("_DesignWidget", RenderContentsInternal(view, pageMode));
        //    }
        //    else
        //        return RenderContentsInternal(view, pageMode);
        //}

        private IHtmlString RenderContentsInternal(WebViewPage view, PageMode pageMode)
        {
            if (Widget == null || string.IsNullOrEmpty(Widget.WidgetName) || string.IsNullOrEmpty(Widget.Controller) || string.IsNullOrEmpty(Widget.Action))
                return null;

            RouteValueDictionary routes = new RouteValueDictionary();
            routes.Add("area", Widget.Area);
            routes.Add("pageMode", pageMode);
            if (!string.IsNullOrEmpty(Parameters))
            {
                var paras = Parameters.ToDictionary("&", "=", "", "");
                foreach (string key in paras.Keys)
                    routes.Add(key, paras[key]);
            }

            if (!string.IsNullOrWhiteSpace(Container))
            {
                return view.Html.Partial(Theme.Container(Container), view.Html.Action(Widget.Action, Widget.Controller, routes));
            }
            else
            {
                return view.Html.Action(Widget.Action, Widget.Controller, routes);
            }
        }

        private string BuildCacheKey(WebViewPage view, PageMode pageMode, string suffix)
        {
            return string.Format("Page:{0};Mode:{1};Widget:{2};Parameters:{3};Type:{4}",
                Page.Name, pageMode, WidgetName, Parameters, suffix);
        }

        [NotMapped]
        public Widget Widget
        {
            get
            {
                return Unity.Current.Resolve<Widget>(WidgetName);
            }
        }

        [NotMapped]
        protected ICacheProvider Cache
        {
            get
            {
                return Unity.Current.Resolve<ICacheProvider>();
            }
        }
    }
}
